/* eslint-disable no-useless-escape */
/* eslint-disable camelcase */

const numberReg = /^-?[1-9][0-9]?.?[0-9]*$/;
const intReg = /^-?[1-9][0-9]*$/;
const phoneReg = /^1(3|4|5|6|7|8|9)\d{9}$/;
const telephoneReg = /^(([0\+]\d{2,3}-)?(0\d{2,3})-)(\d{7,8})(-(\d{3,}))?$/;
const emailReg = /^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/;
const pwdReg = /^.{6,16}$/;
const inviteCodeReg = /^[a-zA-Z0-9]{6,16}$/;
const ip4Reg =
	/^([0-9]|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.([0-9]|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.([0-9]|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.([0-9]|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])$/;
export default {
	isNull: function (val) {
		if (val === null || val === '' || val === 'undefined') {
			return true;
		}
	},
	isNumber: function (val) {
		return numberReg.test(val);
	},
	isInt: function (val) {
		return intReg.test(val);
	},
	isPhone: function (val) {
		return phoneReg.test(val);
	},
	/**
	 * @description 判断数据是否为座机号(固定电话)
	 * @param {String} str_data 待校验的数据
	 * @returns {Boolean}, true:是座机号
	 **/
	isTelephone: function (val) {
		return telephoneReg.test(val);
	},
	isEmail: function (val) {
		return emailReg.test(val);
	},
	isPwd: function (val) {
		return pwdReg.test(val);
	},
	isInviteCode: function (val) {
		return inviteCodeReg.test(val);
	},
	checkCode: function (val) {
		const p = /^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/;
		var factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
		var parity = [1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2];
		var code = val.substring(17);
		if (p.test(val)) {
			var sum = 0;
			for (var i = 0; i < 17; i++) {
				sum += val[i] * factor[i];
			}
			const newCode = parity[sum % 11] + '';
			if (newCode === code.toUpperCase()) {
				return true;
			}
		}
		return false;
	},
	checkDate: function (val) {
		const pattern = /^(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)$/;
		if (pattern.test(val)) {
			const year = val.substring(0, 4);
			const month = val.substring(4, 6);
			const date = val.substring(6, 8);
			const date2 = new Date(year + '-' + month + '-' + date);
			if (date2 && date2.getMonth() === parseInt(month) - 1) {
				return true;
			}
		}
		return false;
	},
	checkProv: function (val) {
		var pattern = /^[1-9][0-9]/;
		var provs = {
			11: '北京',
			12: '天津',
			13: '河北',
			14: '山西',
			15: '内蒙古',
			21: '辽宁',
			22: '吉林',
			23: '黑龙江 ',
			31: '上海',
			32: '江苏',
			33: '浙江',
			34: '安徽',
			35: '福建',
			36: '江西',
			37: '山东',
			41: '河南',
			42: '湖北 ',
			43: '湖南',
			44: '广东',
			45: '广西',
			46: '海南',
			50: '重庆',
			51: '四川',
			52: '贵州',
			53: '云南',
			54: '西藏 ',
			61: '陕西',
			62: '甘肃',
			63: '青海',
			64: '宁夏',
			65: '新疆',
			71: '台湾',
			81: '香港',
			82: '澳门',
		};
		if (pattern.test(val)) {
			if (provs[val]) {
				return true;
			}
		}
		return false;
	},
	/**
	 * 校验身份证
	 * **/
	isIdcard: function (val) {
		if (this.checkCode(val)) {
			var date = val.substring(6, 14);
			if (this.checkDate(date)) {
				if (this.checkProv(val.substring(0, 2))) {
					return true;
				}
			}
		}
		return false;
	},
	/**
	 * @description 判断是否为统一社会信用代码
	 * @param {String} str_data 待校验的数据
	 * @returns {Boolean}, true:社会信用代码正确
	 **/
	isCreditCode: function (str_data) {
		var patrn = /^[0-9A-Z]+$/;
		// 18位校验及大写校验
		if (str_data.length !== 18 || patrn.test(str_data) === false) {
			return false;
		} else {
			var Ancode; // 统一社会信用代码的每一个值
			var Ancodevalue; // 统一社会信用代码每一个值的权重
			var total = 0;
			var weightedfactors = [1, 3, 9, 27, 19, 26, 16, 17, 20, 29, 25, 13, 8, 24, 10, 30, 28]; // 加权因子
			var str = '0123456789ABCDEFGHJKLMNPQRTUWXY';
			// 不用I、O、S、V、Z
			for (var i = 0; i < str_data.length - 1; i++) {
				Ancode = str_data.substring(i, i + 1);
				Ancodevalue = str.indexOf(Ancode);
				total = total + Ancodevalue * weightedfactors[i];
				// 权重与加权因子相乘之和
			}
			var logiccheckcode: any = 31 - (total % 31);
			if (logiccheckcode === 31) {
				logiccheckcode = 0;
			}
			var Str = '0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,T,U,W,X,Y';
			var Array_Str = Str.split(',');
			logiccheckcode = Array_Str[logiccheckcode];
			var checkcode = str_data.substring(17, 18);
			if (logiccheckcode !== checkcode) {
				return false;
			}
			return true;
		}
	},
	/**
	 * @description 判断是否为银行卡号
	 * @param {String} str_cardNo 待校验的数据
	 * @returns {Boolean}, true:是银行卡号
	 **/
	isBankCard: function (str_cardNo) {
		str_cardNo = str_cardNo || String(this);
		if (str_cardNo.trim() === '' || undefined === str_cardNo) {
			return false;
		}
		var lastNum = str_cardNo.substr(str_cardNo.length - 1, 1); // 取出最后一位（与luhm进行比较）
		var first15Num = str_cardNo.substr(0, str_cardNo.length - 1); // 前15或18位
		var newArr: any = [];
		for (var i = first15Num.length - 1; i > -1; i--) {
			// 前15或18位倒序存进数组
			newArr.push(first15Num.substr(i, 1));
		}
		var arrJiShu: any = []; // 奇数位*2的积 <9
		var arrJiShu2: any = []; // 奇数位*2的积 >9
		var arrOuShu: any = []; // 偶数位数组
		for (var j = 0; j < newArr.length; j++) {
			if ((j + 1) % 2 === 1) {
				// 奇数位
				if (parseInt(newArr[j]) * 2 < 9) {
					arrJiShu.push(parseInt(newArr[j]) * 2);
				} else {
					arrJiShu2.push(parseInt(newArr[j]) * 2);
				}
			} else {
				// 偶数位
				arrOuShu.push(newArr[j]);
			}
		}
		var jishu_child1: any = []; // 奇数位*2 >9 的分割之后的数组个位数
		var jishu_child2: any = []; // 奇数位*2 >9 的分割之后的数组十位数
		for (var h = 0; h < arrJiShu2.length; h++) {
			jishu_child1.push(parseInt(arrJiShu2[h]) % 10);
			jishu_child2.push(parseInt(arrJiShu2[h]) / 10);
		}
		var sumJiShu = 0; // 奇数位*2 < 9 的数组之和
		var sumOuShu = 0; // 偶数位数组之和
		var sumJiShuChild1 = 0; // 奇数位*2 >9 的分割之后的数组个位数之和
		var sumJiShuChild2 = 0; // 奇数位*2 >9 的分割之后的数组十位数之和
		var sumTotal = 0;
		for (var m = 0; m < arrJiShu.length; m++) {
			sumJiShu = sumJiShu + parseInt(arrJiShu[m]);
		}
		for (var n = 0; n < arrOuShu.length; n++) {
			sumOuShu = sumOuShu + parseInt(arrOuShu[n]);
		}
		for (var p = 0; p < jishu_child1.length; p++) {
			sumJiShuChild1 = sumJiShuChild1 + parseInt(jishu_child1[p]);
			sumJiShuChild2 = sumJiShuChild2 + parseInt(jishu_child2[p]);
		}
		// 计算总和
		sumTotal = sumJiShu + sumOuShu + sumJiShuChild1 + sumJiShuChild2;
		// 计算Luhm值
		var k = sumTotal % 10 === 0 ? 10 : sumTotal % 10;
		var luhm = 10 - k;
		if (lastNum === luhm) {
			return true;
		} else {
			return false;
		}
	},
	/**
	 * @description 判断数据是否为IPV4地址
	 * @param {String} str_data 待校验的数据
	 * @returns {Boolean}, true:是IPV4地址
	 **/
	isIpV4: function (str_data) {
		str_data = str_data || String(this);
		return ip4Reg.test(str_data);
	},
	/**
	 * @description   判断数据是否为网址(URL),请传入满足http标准协议的链接
	 * @param {String} str_data 待校验的数据
	 * @param {Boolean} flag 是否使用严格模式,默认为false
	 * @returns {Boolean}, true:是网址
	 **/
	isUrl: function (str_data, flag) {
		str_data = str_data || String(this);
		flag = flag || false;
		var regular =
			/^\b(((https?|ftp):\/\/)?[-a-z0-9]+(\.[-a-z0-9]+)*\.(?:com|edu|gov|int|mil|net|org|biz|info|name|museum|asia|coop|aero|[a-z][a-z]|((25[0-5])|(2[0-4]\d)|(1\d\d)|([1-9]\d)|\d))\b(\/[-a-z0-9_:\@&?=+,.!\/~%\$]*)?)$/i;
		var regular2 = /^((https?|ftp):\/\/)(www\.)?\S{0,30}\.\S+$/i;

		if (regular2.test(str_data) && !flag) {
			return true;
		} else if (regular.test(str_data) && flag) {
			return true;
		} else {
			return false;
		}
	},
	validate: function (data, rules) {
		let res = { isOk: true, errmsg: '' };
		if (!rules || !rules.length) {
			return res;
		}
		for (const rule of rules) {
			// rule: {name:'', type:'', errmsg:'', min:1, max:2, eq:'', required:Boolean, regex:''}
			if (!rule || !rule.name || !rule.type) {
				continue;
			}

			// 如果值不存在
			if (!data[rule.name]) {
				// 如果是必填项就返回错误提示，required可以作为type是为了不同的type能给用户不同的提示
				if (rule.type === 'required' || rule.required) {
					res = { isOk: false, errmsg: rule.errmsg };
					if (!res.errmsg) {
						res.errmsg = '请正确输入所有数据'; // 默认提示
					}
					return res;
				}
				// 如果不是必填项就跳过
				continue;
			}
			switch (rule.type) {
				// required 上面已经判断过了
				case 'equals':
				case 'eq':
					if (data[rule.name] !== data[rule.eqName]) {
						res = { isOk: false, errmsg: rule.errmsg };
					}
					break;
				case 'number':
					if (!numberReg.test(data[rule.name])) {
						res = { isOk: false, errmsg: rule.errmsg };
					}
					break;
				case 'int':
					if (!intReg.test(data[rule.name])) {
						res = { isOk: false, errmsg: rule.errmsg };
					}
					break;
				case 'phone':
					if (!phoneReg.test(data[rule.name])) {
						res = { isOk: false, errmsg: rule.errmsg };
					}
					break;
				case 'email':
					if (!emailReg.test(data[rule.name])) {
						res = { isOk: false, errmsg: rule.errmsg };
					}
					break;
				case 'pwd':
					if (!pwdReg.test(data[rule.name])) {
						res = { isOk: false, errmsg: rule.errmsg };
					}
					break;
				case 'inviteCode':
					if (!inviteCodeReg.test(data[rule.name])) {
						res = { isOk: false, errmsg: rule.errmsg };
					}
					break;
				case 'range': { // {name: 'xxx', type: 'range', min: 6, max: 6, required: true, errmsg: 'xxx'} // 数字类型的值取值范围
					const val = data[rule.name];
					if (val) {
						if (numberReg.test(val)) {
							if (rule.min && val < rule.min) {
								res = { isOk: false, errmsg: rule.errmsg };
							} else if (rule.max && val > rule.max) {
								res = { isOk: false, errmsg: rule.errmsg };
							}
						} else {
							res = { isOk: false, errmsg: rule.errmsg };
						}
					}
					break;
				}
				case 'lengthRange': { // {name: 'xxx', type: 'lengthRange', min: 6, max: 6, errmsg: 'xxx'} // 字符串长度取值范围
					const le = data[rule.name] ? data[rule.name].length : 0;
					if (rule.min && le < rule.min) {
						res = { isOk: false, errmsg: rule.errmsg };
					} else if (rule.max && le > rule.max) {
						res = { isOk: false, errmsg: rule.errmsg };
					}
					break;
				}
				case 'regex': // 自定义正则表达式
					// {name: 'xxx', type: 'regex', regex: /^1[0-9]{10,10}$/, errmsg: 'xxx'}
					if (rule.regex && !rule.regex.test(data[rule.name])) {
						res = { isOk: false, errmsg: rule.errmsg };
					}
					break;
			}
			// 发现任何一个错误就立即返回，后面的不再判断
			if (!res.isOk) {
				if (!res.errmsg) {
					res.errmsg = '请正确输入所有数据'; // 默认提示
				}
				return res;
			}
		}
		return res;
	},
};
